#pragma once

#include "hzpch.h"
#include "Core/Core.h"

namespace Hazel{
    class Log {
    public:
        Log();
        ~Log();

        static void Init();

        inline static Ref<spdlog::logger>& GetCoreLogger(){return s_CoreLogger;}
        inline static Ref<spdlog::logger>& GetClientLogger(){return s_ClientLogger;}

        inline static void PrintGlm(glm::mat4 covarMat4){
//            std::cout << " " << std::endl;
//            for (int i = 0; i < 4; ++i) {
//                std::cout << "[";
//                for (int j = 0; j < 4; ++j) {
//                    std::cout << matrix[i][j] << " ";
//                }
//                std::cout << "]" << std::endl;
//            }
            std::cout << std::setprecision(20) << covarMat4[0][0] << "  " << covarMat4[1][0] << "  " << covarMat4[2][0] << "  " << covarMat4[3][0] << std::endl;
            std::cout << std::setprecision(20) << covarMat4[0][1] << "  " << covarMat4[1][1] << "  " << covarMat4[2][1] << "  " << covarMat4[3][1] << std::endl;
            std::cout << std::setprecision(20) << covarMat4[0][2] << "  " << covarMat4[1][2] << "  " << covarMat4[2][2] << "  " << covarMat4[3][2] << std::endl;
            std::cout << std::setprecision(20) << covarMat4[0][3] << "  " << covarMat4[1][3] << "  " << covarMat4[2][3] << "  " << covarMat4[3][3] << std::endl;
        }
        inline static void PrintVec(glm::vec4 vec){
            std::cout << " ["<< vec.x <<"," << vec.y <<","<< vec.z <<","<< vec.w << "] " << std::endl;
        }

    private:
        static Ref<spdlog::logger> s_CoreLogger;
        static Ref<spdlog::logger> s_ClientLogger;
    };
}

// Core log macros
#define HZ_CORE_TRACE(...)    ::Hazel::Log::GetCoreLogger()->trace(__VA_ARGS__)
#define HZ_CORE_INFO(...)     ::Hazel::Log::GetCoreLogger()->info(__VA_ARGS__)
#define HZ_CORE_WARN(...)     ::Hazel::Log::GetCoreLogger()->warn(__VA_ARGS__)
#define HZ_CORE_ERROR(...)    ::Hazel::Log::GetCoreLogger()->error(__VA_ARGS__)
#define HZ_CORE_FATAL(...)    ::Hazel::Log::GetCoreLogger()->fatal(__VA_ARGS__)
#define HZ_CORE_CRITICAL(...) ::Hazel::Log::GetCoreLogger()->critical(__VA_ARGS__)

// Client log macros
#define HZ_TRACE(...)	      ::Hazel::Log::GetClientLogger()->trace(__VA_ARGS__)
#define HZ_INFO(...)	      ::Hazel::Log::GetClientLogger()->info(__VA_ARGS__)
#define HZ_WARN(...)	      ::Hazel::Log::GetClientLogger()->warn(__VA_ARGS__)
#define HZ_ERROR(...)	      ::Hazel::Log::GetClientLogger()->error(__VA_ARGS__)
#define HZ_FATAL(...)	      ::Hazel::Log::GetClientLogger()->fatal(__VA_ARGS__)
#define HZ_CRITICAL(...)      ::Hazel::Log::GetClientLogger()->critical(__VA_ARGS__)

#define HZ_GLM4(mat)   ::Hazel::Log::PrintGlm(mat)
#define HZ_VEC4(vec)   ::Hazel::Log::PrintVec(vec)